/*****************************************************************************
#
#
******************************************************************************/
#include "EPD_2in15_test.h"
#include "DEBUG.h"
// #include "EPD_SDCard.h"

#define DEBUG Debug

static uint8_t iLut = 0;

/******************************************************************************
function :	Software reset
parameter:
******************************************************************************/
static void EPD_2IN15_test_Reset(void)
{
    // DEV_Digital_Write(EPD_RST_PIN, 1);
    // DEV_Delay_ms(10);
    DEV_Digital_Write(EPD_RST_PIN, 0);
    DEV_Delay_ms(10);
    DEV_Digital_Write(EPD_RST_PIN, 1);
    DEV_Delay_ms(10);
}

/******************************************************************************
function :	send command
parameter:
     Reg : Command register
******************************************************************************/
static void EPD_2IN15_test_SendCommand(UBYTE Reg)
{
    DEV_Digital_Write(EPD_DC_PIN, 0);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Reg);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

/******************************************************************************
function :	send data
parameter:
    Data : Write data
******************************************************************************/

static void EPD_2IN15_test_SendData(UBYTE Data)
{
    DEV_Digital_Write(EPD_DC_PIN, 1);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Data);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

static void EPD_2IN15_test_SendData2(UBYTE *Data, UDOUBLE length)
{
    DEV_SPI_WriteByte(Data, length);
}

static void EPD_2IN15_test_SendData2(UBYTE Data)
{
    // DEV_Digital_Write(EPD_DC_PIN, 1);
    // DEV_Digital_Write(EPD_CS_PIN, 0);
    DEV_SPI_WriteByte(Data);
    // DEV_Digital_Write(EPD_CS_PIN, 1);
}

/******************************************************************************
function :	Wait until the busy_pin goes LOW
parameter:
******************************************************************************/
static void EPD_2IN15_test_ReadBusy(void)
{
    DEBUG("e-Paper busy\r\n");
    while (1)
    {
        if (DEV_Digital_Read(EPD_BUSY_PIN) == 1)
            break;
        DEV_Delay_ms(10);
    }

    DEBUG("e-Paper busy release\r\n");
}

void EPD_2IN15_test_ReadBusy(uint32_t ms)
{
    Debug("e-Paper busy:%d\r\n", millis());
    for (uint32_t i = 0; i < ms; i += 10)
    {
        if (DEV_Digital_Read(EPD_BUSY_PIN))
        {
            Debug("e-Paper busy release:%d\r\n", millis());
            return;
        }
        if (ms > 200)
        {
#ifndef TEST
            EPD_BUSY_attachInterrupt(LOW);
#else
            DEV_Delay_ms(10);
#endif
        }
        else
            DEV_Delay_ms(10);
    }
    Debug("e-Paper busy timeout:%d\r\n", millis());
}

#define _VS(x) x << 6
#define VSS _VS(0b00)
#define VSH1 _VS(0b01)
#define VSL _VS(0b10)
#define VSH2 _VS(0b11)

/* LUT lite is small than LUT used in SSD1680A, only 35 bytes.
 * lut_lite_fast_bw is default lut for clock display,
 * lut_lite_gray8_bwr is default lut for BLE display.
 */
#define LUT_LITE_LEN 35
// LUT for BLE Gray display (8 steps)//8grey
static const uint8_t lut_lite_grey8_bwr[LUT_LITE_LEN] = {
    //  RP      A           B           C           D           SRAB    SRCD
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTC
    0x1, VSH2 | 0x2F, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTR
    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,         // LUTW
    0x1, VSH1 | 0x05, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB

    //  FR
    0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     5v      -15v
    0x22, 0x0, 0x41, 0xA8, 0x32, 0x0};

static const uint8_t lut_lite_grey8_bwr_array[7][4] = {
    {VSH2 | 0x1, 0x34, VSH1 | 0x05, 0x01}, // ilut1
    {VSH2 | 0x1, 0x2F, VSH1 | 0x05, 0x01}, // ilut2
    {VSH2 | 0x1, 0x2F, VSH1 | 0x05, 0x01}, // ilut3
    {VSH2 | 0x1, 0x1A, VSH1 | 0x05, 0x01}, // ilut4
    {VSH2 | 0x1, 0x15, VSH1 | 0x05, 0x01}, // ilut5
    {VSH2 | 0x1, 0x15, VSH1 | 0x05, 0x01}, // ilut6
    {VSH2 | 0x1, 0x2D, VSH1 | 0x05, 0x01}, // ilut7
};

static void EPD_2IN15_test_Lut(const unsigned char *lut)
{
    // SSD1680A uses 233 LUT.

    // 0, wareform setting
    EPD_2IN15_test_SendCommand(0x32);
    for (int j = 0; j < 4; j++)
    { // LUT0-3
        // wave setting
        for (int i = 0; i < 7; i++)
        {
            EPD_2IN15_test_SendData(lut[j * 7 + i]);
        }
        // no config
        for (int i = 0; i < 7 * 7; i++)
        {
            EPD_2IN15_test_SendData(0x00);
        }
    }
    // 4 * (7+49) = 224

    // 224, FR
    // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
    EPD_2IN15_test_SendData(lut[28]);

    // 225, XON
    EPD_2IN15_test_SendData(0x00);
    EPD_2IN15_test_SendData(0x00);

    //  EOPT    VGH     VSH1    VSH2    VSL     VCOM
    //  3F      03      04                      2C
    //  22      -20v    15v     3v      -15v
    //  0x22,   0x17,   0x41,   0x94,   0x32,   0x36

    // // 227, gate voltage
    // EPD_2IN15_test_SendCommand(0x3F);
    // EPD_2IN15_test_SendData(lut[29]);

    // EPD_2IN15_test_SendCommand(0x03);
    // EPD_2IN15_test_SendData(lut[30]);

    // // 229, source voltage
    // EPD_2IN15_test_SendCommand(0x04);
    // EPD_2IN15_test_SendData(lut[31]); // VSH
    // EPD_2IN15_test_SendData(lut[32]); // VSH2
    // EPD_2IN15_test_SendData(lut[33]); // VSL

    // // 232, VCOM
    // EPD_2IN15_test_SendCommand(0x2C);
    // EPD_2IN15_test_SendData(lut[34]);
}

// full screen update LUT
// const unsigned char lut_20_vcomDC[] PROGMEM =
//     {
//         0x00,
//         0x08,
//         0x00,
//         0x00,
//         0x00,
//         0x02,
//         0x60,
//         0x28,
//         0x28,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x14,
//         0x00,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x12,
//         0x12,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
// };

// const unsigned char lut_21_ww[] PROGMEM =
//     {
//         0x40,
//         0x08,
//         0x00,
//         0x00,
//         0x00,
//         0x02,
//         0x90,
//         0x28,
//         0x28,
//         0x00,
//         0x00,
//         0x01,
//         0x40,
//         0x14,
//         0x00,
//         0x00,
//         0x00,
//         0x01,
//         0xA0,
//         0x12,
//         0x12,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
// };

// const unsigned char lut_22_bw[] PROGMEM =
//     {
//         0x40,
//         0x08,
//         0x00,
//         0x00,
//         0x00,
//         0x02,
//         0x90,
//         0x28,
//         0x28,
//         0x00,
//         0x00,
//         0x01,
//         0x40,
//         0x14,
//         0x00,
//         0x00,
//         0x00,
//         0x01,
//         0xA0,
//         0x12,
//         0x12,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
// };

// const unsigned char lut_23_wb[] PROGMEM =
//     {
//         0x80,
//         0x08,
//         0x00,
//         0x00,
//         0x00,
//         0x02,
//         0x90,
//         0x28,
//         0x28,
//         0x00,
//         0x00,
//         0x01,
//         0x80,
//         0x14,
//         0x00,
//         0x00,
//         0x00,
//         0x01,
//         0x50,
//         0x12,
//         0x12,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
// };

// const unsigned char lut_24_bb[] PROGMEM =
//     {
//         0x80,
//         0x08,
//         0x00,
//         0x00,
//         0x00,
//         0x02,
//         0x90,
//         0x28,
//         0x28,
//         0x00,
//         0x00,
//         0x01,
//         0x80,
//         0x14,
//         0x00,
//         0x00,
//         0x00,
//         0x01,
//         0x50,
//         0x12,
//         0x12,
//         0x00,
//         0x00,
//         0x01,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
//         0x00,
// };

unsigned char lut_20_vcomDC[] =
{
    0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A, 
    0x00, 0x00, 0x08, 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x00, 0x0A, 
    0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 
    0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01    
};

//R21H
unsigned char lut_21_ww[] =
{
    0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x84, 0x0E, 
    0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 
    0x00, 0x05, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
};

//R22H    r
unsigned char lut_22_bw[] =
{
    0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x84, 0x0E, 
    0x01, 0x0E, 0x01, 0x10, 0x90, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0xB0, 0x04, 0x10, 0x00, 
    0x00, 0x05, 0xB0, 0x03, 0x0E, 0x00, 0x00, 0x0A, 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01
};

//R23H    w
unsigned char lut_23_wb[] =
{
    0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x84, 0x0E, 
    0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00,
    0x00, 0x05, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
};

//R24H    b
unsigned char lut_24_bb[] =
{
    0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x20, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x84, 0x0E, 
    0x01, 0x0E, 0x01, 0x10, 0x10, 0x0A, 0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 
    0x00, 0x05, 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
};

// const unsigned char lut_20_vcomDC[] ={
// 0x00  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
//   ,0x00 ,0x00,          };
// const unsigned char lut_21_ww[] ={
// 0x00  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,};
// const unsigned char lut_22_bw[] ={
// 0x80  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  };
// const unsigned char lut_23_wb[] ={
// 0x40  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  };
// const unsigned char lut_24_bb[] ={
// 0x00  ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  
// 0x00  ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,  };


static void EPD_2IN15_test_Lut(const uint8_t *LUT, uint8_t LUT_SIZE)
{
    for (int i = 0; i < LUT_SIZE; i++)
    {
        EPD_2IN15_test_SendData(LUT[i]);
    }
}

/******************************************************************************
function :	Initialize the e-Paper register
parameter:
******************************************************************************/
void EPD_2IN15_test_Init(uint8_t lut_type)
{

    EPD_2IN15_test_Reset();

    // EPD_2IN15_test_ReadBusy(100);
    // EPD_2IN15_test_SendCommand(0x12); // SWRESET
    // EPD_2IN15_test_ReadBusy(100);

    // EPD_2IN15_test_SendCommand(0x01); // Driver output control
    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) % 256);
    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) / 256);
    // EPD_2IN15_test_SendData(0x00);

    // EPD_2IN15_test_SendCommand(0x11); // data entry mode
    // EPD_2IN15_test_SendData(0x03);

    // EPD_2IN15_test_SendCommand(0x44); // set Ram-X address start/end position
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendData(EPD_2IN15_test_WIDTH / 8 - 1);

    // EPD_2IN15_test_SendCommand(0x45); // set Ram-Y address start/end position
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) % 256);
    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) / 256);

    // EPD_2IN15_test_SendCommand(0x3C); // BorderWavefrom
    // EPD_2IN15_test_SendData(0x05);

    // EPD_2IN15_test_SendCommand(0x21); //  Display update control
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendData(0x40);

    // EPD_2IN15_test_SendCommand(0x18); // Read built-in temperature sensor
    // EPD_2IN15_test_SendData(0x80);

    // EPD_2IN15_test_SendCommand(0x4E); // set RAM x address count to 0;
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendCommand(0x4F); // set RAM y address count to 0X199;
    // EPD_2IN15_test_SendData(0x00);
    // EPD_2IN15_test_SendData(0x00);

    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) % 256);
    // EPD_2IN15_test_SendData((EPD_2IN15_test_HEIGHT - 1) / 256);

    //  if (lut_type)
    // {
    //     if (lut_type == EPD_2IN15_test_Bwr8)
    //     {
    //         uint8_t lut_temp[LUT_LITE_LEN];
    //         memcpy(lut_temp, lut_lite_grey8_bwr, LUT_LITE_LEN);
    //         if (iLut > 0 && iLut < 8)
    //         {
    //             lut_temp[8] = lut_lite_grey8_bwr_array[iLut - 1][0];
    //             lut_temp[12] = lut_lite_grey8_bwr_array[iLut - 1][1];
    //             lut_temp[22] = lut_lite_grey8_bwr_array[iLut - 1][2];
    //             lut_temp[26] = lut_lite_grey8_bwr_array[iLut - 1][3];
    //         }
    //         EPD_2IN15_test_Lut(lut_temp);
    //     }
    // }

    // EPD_2IN15_test_ReadBusy(100);

    EPD_2IN15_test_SendCommand(0x04);
    EPD_2IN15_test_ReadBusy(1000); // waiting for the electronic paper IC to release the idle signal
    
    EPD_2IN15_test_SendCommand(0x00); // panel setting
    EPD_2IN15_test_SendData(0xAf);    // LUT from OTP��?KW-BF   KWR-AF  BWROTP 0f BWOTP 1f
        // EPD_2IN15_test_SendData(0xBf);    // LUT from OTP��?KW-BF   KWR-AF  BWROTP 0f BWOTP 1f
    EPD_2IN15_test_SendCommand(0x30); // PLL setting
    EPD_2IN15_test_SendData(0x3a);    // 3a 100HZ   29 150Hz 39 200HZ 31 171HZ

    EPD_2IN15_test_SendCommand(0x01); // POWER SETTING
    EPD_2IN15_test_SendData(0x03);
    EPD_2IN15_test_SendData(0x00);
    EPD_2IN15_test_SendData(0x2b);
    EPD_2IN15_test_SendData(0x2b);
    EPD_2IN15_test_SendData(0x09);

    EPD_2IN15_test_SendCommand(0x06); // boost soft start
    EPD_2IN15_test_SendData(0x07);    // A
    EPD_2IN15_test_SendData(0x07);    // B
    EPD_2IN15_test_SendData(0x17);    // C

    // EPD_2IN15_test_SendCommand(0xF8); 
    // EPD_2IN15_test_SendData(0x60);  
    // EPD_2IN15_test_SendData(0xA5);  
    //  EPD_2IN15_test_SendCommand(0xF8); 
    // EPD_2IN15_test_SendData(0x89);  
    // EPD_2IN15_test_SendData(0xA5);
    //     EPD_2IN15_test_SendCommand(0xF8); 
    // EPD_2IN15_test_SendData(0x90);  
    // EPD_2IN15_test_SendData(0x00);
    //     EPD_2IN15_test_SendCommand(0xF8); 
    // EPD_2IN15_test_SendData(0x93);  
    // EPD_2IN15_test_SendData(0x2a);
    //     EPD_2IN15_test_SendCommand(0xF8); 
    // EPD_2IN15_test_SendData(0x73);  
    // EPD_2IN15_test_SendData(0x41);
    


    // EPD_2IN15_test_SendData(0x0D);

    EPD_2IN15_test_SendCommand(0x82); // vcom_DC setting
    EPD_2IN15_test_SendData(0x12);
    EPD_2IN15_test_SendCommand(0X50); // VCOM AND DATA INTERVAL SETTING
    EPD_2IN15_test_SendData(0x97);    // WBmode:VBDF 17|D7 VBDW 97 VBDB 57   WBRmode:VBDF F7 VBDW 77 VBDB 37  VBDR B7

    EPD_2IN15_test_SendCommand(0x20);
    EPD_2IN15_test_Lut(lut_20_vcomDC, sizeof(lut_20_vcomDC));
    EPD_2IN15_test_SendCommand(0x21);
    EPD_2IN15_test_Lut(lut_21_ww, sizeof(lut_21_ww));
    EPD_2IN15_test_SendCommand(0x22);
    EPD_2IN15_test_Lut(lut_22_bw, sizeof(lut_22_bw));
    EPD_2IN15_test_SendCommand(0x23);
    EPD_2IN15_test_Lut(lut_23_wb, sizeof(lut_23_wb));
    EPD_2IN15_test_SendCommand(0x24);
    EPD_2IN15_test_Lut(lut_24_bb, sizeof(lut_24_bb));


    EPD_2IN15_test_SendCommand(0x61); // resolution setting
    // EPD_2IN15_test_SendData(0);
    EPD_2IN15_test_SendData(EPD_2IN15_test_WIDTH);
    EPD_2IN15_test_SendData(EPD_2IN15_test_HEIGHT / 256);
    EPD_2IN15_test_SendData(EPD_2IN15_test_HEIGHT % 256);

    // EPD_2IN15_test_SendCommand(0x16); 
    // EPD_2IN15_test_SendData(0x00);




}

/******************************************************************************
function :	Clear screen
parameter:
******************************************************************************/
void EPD_2IN15_test_Clear(void)
{
    UDOUBLE Width, Height;
    Width = (EPD_2IN15_test_WIDTH % 8 == 0) ? (EPD_2IN15_test_WIDTH / 8) : (EPD_2IN15_test_WIDTH / 8 + 1);
    Height = EPD_2IN15_test_HEIGHT;

    unsigned int i;
    // EPD_2IN15_test_SendCommand(0x24); // write RAM for black(0)/white (1)
    EPD_2IN15_test_SendCommand(0x10); // write RAM for black(0)/white (1)
    DEV_Digital_Write(EPD_DC_PIN, 1);
    for (i = 0; i < Width * Height; i++)
    {
        EPD_2IN15_test_SendData(0xFF);
        // EPD_2IN15_test_SendData2(0x00);
    }

    EPD_2IN15_test_SendCommand(0x13); // write RAM for black(0)/white (1)
    DEV_Digital_Write(EPD_DC_PIN, 1);
    for (i = 0; i < Width * Height; i++)
    {
        EPD_2IN15_test_SendData(0xFF);
        // EPD_2IN15_test_SendData2(0x00);
    }
    // EPD_2IN15_test_SendCommand(0x26); // write RAM for black(0)/white (1)
    // DEV_Digital_Write(EPD_DC_PIN, 1);
    // for (i = 0; i < Width * Height; i++)
    // {
    //     // EPD_2IN15_test_SendData(0x00);
    //     EPD_2IN15_test_SendData2(0x00);
    // }
    // EPD_2IN15_test_SendCommand(0x22); // Display Update Control
    // // EPD_2IN15_test_SendData(0xF7);
    //     EPD_2IN15_test_SendData(0xC7);
    // EPD_2IN15_test_SendCommand(0x20);   // Activate Display Update Sequence
    EPD_2IN15_test_SendCommand(0x12); // Display Update Control

    EPD_2IN15_test_ReadBusy(30 * 1000); // 9s
}

/******************************************************************************
function :	Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_2IN15_test_Display(unsigned char *BW_Image)
// void EPD_2IN15_test_Display(unsigned char *BW_Image, unsigned char *R_Image)
{
    UDOUBLE Width, Height;
    Width = (EPD_2IN15_test_WIDTH % 8 == 0) ? (EPD_2IN15_test_WIDTH / 8) : (EPD_2IN15_test_WIDTH / 8 + 1);
    Height = EPD_2IN15_test_HEIGHT;

    // send black data

    EPD_2IN15_test_SendCommand(0x24);
    DEV_Digital_Write(EPD_DC_PIN, 1);
    EPD_2IN15_test_SendData2(BW_Image, Width * Height);

    // EPD_2IN15_test_SendCommand(0x26);
    // DEV_Digital_Write(EPD_DC_PIN, 1);
    // EPD_2IN15_test_SendData2(R_Image, Width * Height);

    EPD_2IN15_test_SendCommand(0x22); // Display Update Control
    EPD_2IN15_test_SendData(0xC7);
    // EPD_2IN15_test_SendData(0xF7);
    EPD_2IN15_test_SendCommand(0x20); // Activate Display Update Sequence
    EPD_2IN15_test_ReadBusy(30 * 1000);
}

/******************************************************************************
function :	Enter sleep mode
parameter:
******************************************************************************/
void EPD_2IN15_test_Sleep(void)
{
    EPD_2IN15_test_SendCommand(0x10); // enter deep sleep
    EPD_2IN15_test_SendData(0x01);
    DEV_Delay_ms(100);
}

/******************************************************************************
function :	Turn On Display
parameter:
******************************************************************************/
// void EPD_2IN15_test_TurnOnDisplay(void)
// {
//     EPD_2IN15_test_SendCommand(0x22); // Display Update Control
//     EPD_2IN15_test_SendData(0xF7);
//     EPD_2IN15_test_SendCommand(0x20); // Activate Display Update Sequence
//     EPD_2IN15_test_ReadBusy(15 * 1000);
// }

void EPD_2IN15_test_TurnOnDisplay(uint8_t part)
{
    EPD_2IN15_test_SendCommand(0x22); // Display Update Control
    EPD_2IN15_test_SendData(part ? 0xC7 : 0xF7);
    EPD_2IN15_test_SendCommand(0x20); // Activate Display Update Sequence
    EPD_2IN15_test_ReadBusy(30 * 1000);
}

/******************************************************************************
function :	Sends the image buffer in RAM to e-Paper and displays
parameter:  color:black,0;red,1;*data;index;length
******************************************************************************/
void EPD_2IN15_test_Data_Write(UBYTE color, UBYTE *Image_Data, UDOUBLE index, UDOUBLE length)
{
    if (index == 0)
    // if (1)
    {
        if (color == 0)
        {
            EPD_2IN15_test_SendCommand(0x24);
        }
        else if (color == 1)
        {
            EPD_2IN15_test_SendCommand(0x26);
        }
        DEV_Digital_Write(EPD_DC_PIN, 1);
    }

    UDOUBLE Width, Height;
    Width = (EPD_2IN15_test_WIDTH % 8 == 0) ? (EPD_2IN15_test_WIDTH / 8) : (EPD_2IN15_test_WIDTH / 8 + 1);
    Height = EPD_2IN15_test_HEIGHT;

    // if(length==(Width*Height))
    // {
    //     for (UDOUBLE j = 0; j < Height; j++)
    //     {
    //         for (UDOUBLE i = 0; i < Width; i++)
    //         {
    //             EPD_2IN15_test_SendData(Image_Data[i + (Height-j) * Width]);
    //         }
    //     }

    // }
    // else{
#ifdef EPD_SPI_ENABLE
    EPD_2IN15_test_SendData2(Image_Data, length);
#else
    for (UDOUBLE i = 0; i < length; i++)
    {
        if (color == 0)
        {
            // DEV_Digital_Write(EPD_DC_PIN, 1);
            // DEV_Digital_Write(EPD_CS_PIN, 0);
            EPD_2IN15_test_SendData2(Image_Data[i]);
            // DEV_Digital_Write(EPD_CS_PIN, 1);
        }
        else if (color == 1)
        {
            // DEV_Digital_Write(EPD_DC_PIN, 1);
            // DEV_Digital_Write(EPD_CS_PIN, 0);
            EPD_2IN15_test_SendData2(Image_Data[i]);
            // DEV_Digital_Write(EPD_CS_PIN, 1);
        }
    }
#endif
    // }
}

void EPD_2IN15_test_setDepth(uint8_t i)
{
    iLut = i ? (i > 15 ? 15 : i) : 15;
}

#if 1
int8_t EPD_2IN15_test_ReadTemp()
{
    int8_t rc = 0;

    // EPD_2IN15_test_SendCommand(0x12); // soft reset
    // EPD_SSD_WaitBusy(100);
    // EPD_2IN15_test_Reset();

    // EPD_2IN15_test_ReadBusy(100);
    EPD_2IN15_test_SendCommand(0x12); // SWRESET
    // EPD_2IN15_test_ReadBusy(1000);
    DEV_Delay_us(200);

    // Border Waveform
    EPD_2IN15_test_SendCommand(0x3C);
    EPD_2IN15_test_SendData(0x05);

    // Temperature sensor control
    EPD_2IN15_test_SendCommand(0x18);
    EPD_2IN15_test_SendData(0x80); // 80: internal sensor 48: external sensor

    // Display update control
    EPD_2IN15_test_SendCommand(0x22);
    EPD_2IN15_test_SendData(0xb1); // full: 0xf7

    // Master Activation
    EPD_2IN15_test_SendCommand(0x20);
    // EPD_SSD_WaitBusy(100);
    EPD_2IN15_test_ReadBusy();

    // read temperature
    EPD_2IN15_test_SendCommand(0x1b);
    rc = EPD_SSD_ReadData();

    return rc;
}
#endif
